Use Case 1: face_recognition¶
Contents¶
I. Mannual Process¶
- Demonstrating how we can conduct the facial recognition process manually
II. Automate the Process¶
- By encoding all the images and wrap all the distance calculation in a function, this step shows how we can automate the entire facial comparision process
III. Performance Evaluation¶
- After conducting all the facial comparision in the previous step, we can evaluate the outcomes, and assess the performance of the library on our images.
IV. Examples¶
- Display some facial comparision along with their similarities. These examples contains expected matches and expected non-matches
I. Mannual Process¶
In this manual process, I am going to demonstrate the manual way to compare two faces.
import pandas as pd
import numpy as np
import subprocess
import sys
import matplotlib.pyplot as plt
import seaborn as sns
import face_recognition
from PIL import Image, ImageDraw, ImageFont, ImageFilter, ImageOps, ImageEnhance
import os
import pickle
from sklearn.metrics import confusion_matrix, accuracy_score, precision_score, recall_score
# import image to python and load the image
image_file = '2024_students/Boyan_Wei_aged.jpg'
image = Image.open(image_file)
# resize the image
width , height = image.size
print('Original image size: ', width, height)
image = image.resize((int(width/4), int(height/4)))
# new size of the image
width , height = image.size
print('New image size: ', width, height)
# display the image
display(image)
Original image size: 1024 1024 New image size: 256 256
Loop over the excel file to obtain the names of all images in the msba folder
match_file = pd.read_excel('image_name.xlsx')
# eyeball the dataset
match_file.head()
| match_id | source_image | name | target_image | expected_match | |
|---|---|---|---|---|---|
| 0 | 100 | Bingyu_Li.jpg | Bingyu_Li | Bingyu_Li_aged.jpg | match |
| 1 | 101 | Whitney_Joyce_Isbell.jpg | Whitney_Joyce_Isbell | Whitney_Joyce_Isbell_aged.jpg | match |
| 2 | 102 | Qian_Chen.jpg | Qian_Chen | Qian_Chen_aged.jpg | match |
| 3 | 103 | Hanshuai_Shi.jpg | Hanshuai_Shi | Hanshuai_Shi_aged.jpg | match |
| 4 | 104 | Ruochen_Bao.jpg | Ruochen_Bao | Ruochen_Bao_aged.jpg | match |
I would like to display the two faces next to each other, and place the similarity in the middle
def display_compare_face(image_file, match_file):
"""
Args:
image_file: image to be compared (shown on the left)
match_file: image to be compared with (shown on the right)
return:
display the two images side by side with its similarity score
"""
image1 = face_recognition.load_image_file(image_file)
image2 = face_recognition.load_image_file(match_file)
# calculate the distance between the two faces
img1_encoding = face_recognition.face_encodings(image1)[0]
img2_encoding = face_recognition.face_encodings(image2)[0]
face_distance = face_recognition.face_distance([img1_encoding], img2_encoding)
# normalize the distance to get the similarity score
similarity = 1 - face_distance[0]
image1 = Image.open(image_file)
image2 = Image.open(match_file)
# Resize the second image to match the first image's size
image1 = image1.resize(image2.size)
# Create a new blank image with a size equal to the sum of the widths of the two images
new_image_width = image1.width * 2
new_image_height = image1.height
new_image = Image.new("RGB", (new_image_width, new_image_height))
# Paste the first image onto the new image at position (0, 0)
new_image.paste(image1, (0, 0))
# Paste the second image onto the new image at position (image1.width, 0)
new_image.paste(image2, (image1.width, 0))
# Add text to the image
text = '{} % MATCH'.format(int(similarity*100))
font_path = "2024_students/Roboto-Medium.ttf" # Ensure this path is correct
font = ImageFont.truetype(font_path, size=48)
draw = ImageDraw.Draw(new_image)
# Calculate the text position
# text_width, text_height = draw.textsize((0,0), text, font)
left, top, right, bottom = draw.textbbox((0,0), text, font)
text_width = right - left
text_height = bottom - top
text_x = (new_image_width - text_width)/2
text_y = (new_image_height - text_height)/2
# Draw the text over the rectangle
draw.text((text_x, text_y), text, font=font, fill=(0, 0, 0, 255))
# display the image
display(new_image)
# 1. Load two images using load_image_file
face_file1 = "2024_students/Boyan_Wei.jpg"
face_file2 = "2024_students/Boyan_Wei_aged.jpg"
image1 = face_recognition.load_image_file(face_file1)
image2 = face_recognition.load_image_file(face_file2)
# 2. Compare the face_encodings similarity using face_distance
img1_encoding = face_recognition.face_encodings(image1)[0]
img2_encoding = face_recognition.face_encodings(image2)[0]
# Calculate the distance between the faces
face_distance = face_recognition.face_distance([img1_encoding], img2_encoding)
# Normalize the distance to get the similarity score
similarity = 1 - face_distance[0]
# Print the similarity score
print("The two faces are '{:.2f}%' similar".format(similarity*100))
The two faces are '66.68%' similar
# 3. is it a match?
face_matches = face_recognition.compare_faces([img1_encoding], img2_encoding) # default threshold is 0.6
# Print the result
if face_matches[0]:
print("The two faces match")
else:
print("The two faces do not match")
The two faces match
# Open the two image files
image1 = Image.open(face_file1)
image2 = Image.open(face_file2)
# Resize the second image to match the first image's size
image1 = image1.resize(image2.size)
# Create a new blank image with a size equal to the sum of the widths of the two images
new_image_width = image1.width * 2
new_image_height = image1.height
new_image = Image.new("RGB", (new_image_width, new_image_height))
# Paste the first image onto the new image at position (0, 0)
new_image.paste(image1, (0, 0))
# Paste the second image onto the new image at position (image1.width, 0)
new_image.paste(image2, (image1.width, 0))
# Add text to the image
text = '{} % MATCH'.format(int(similarity*100))
font_path = "2024_students/Roboto-Medium.ttf" # Ensure this path is correct
font = ImageFont.truetype(font_path, size=48)
draw = ImageDraw.Draw(new_image)
# Calculate the text position
# text_width, text_height = draw.textsize((0,0), text, font)
left, top, right, bottom = draw.textbbox((0,0), text, font)
text_width = right - left
text_height = bottom - top
text_x = (new_image_width - text_width)/2
text_y = (new_image_height - text_height)/2
# Draw the text over the rectangle
draw.text((text_x, text_y), text, font=font, fill=(0, 0, 0, 255))
# display the image
display(new_image)
II. Automate the Process¶
List all the "images" from our cohort and put them in one list
dir_name = '2024_students'
def list_jpeg_files(directory):
"""List all JPEG files in the specified directory."""
jpeg_files = [file for file in os.listdir(directory) if file.lower().endswith(('.jpeg', '.jpg'))]
return jpeg_files
directory_path = './2024_students'
jpeg_files = list_jpeg_files(directory_path)
print("JPEG files in the directory:", jpeg_files)
JPEG files in the directory: ['Dongqiao_Tang_aged.jpg', 'Hewei_Shen_aged.jpg', 'Jackson_R_Harper_aged.jpg', 'Wei_Tan.jpg', 'Nathanael_Hunter_Kraus.jpg', 'Benjamin_Pyung-Hwa_Aikens_aged.jpg', 'Helen_Kidane_Haile_aged.jpg', 'Samantha_O_Brien_aged.jpg', 'Yiming_Xu_aged.jpg', 'Manling_Shi_aged.jpg', 'Meghan_O_Malley.jpg', 'Eric_Mayo.jpg', 'Haopeng_Liu.jpg', 'Wei_Tan_aged.jpg', 'Jennifer_Ontiveros-Olivas.jpg', 'Nicholas_J_Sundberg_aged.jpg', 'Patrick_Ryan_Weimaker.jpg', 'Zihe_Liu_aged.jpg', 'Manling_Shi.jpg', 'Amanda_Renner_Gild_aged.jpg', 'George_Basil_Economus.jpg', 'Michelle_Monica_Saikali.jpg', 'Joseph_Macon_Barker.jpg', 'Kaitlyn_R_Vickers_aged.jpg', 'Andrea_Chen.jpg', 'Kyle_John_Wiblishauser.jpg', 'Skylour_Sebastian_Winakur.jpg', 'Logan_Trujillo.jpg', 'Xingyu_Wan.jpg', 'Cole_Ritchey_aged.jpg', 'Jiacheng_Wang_aged.jpg', 'Garhett_William_Sessions_aged.jpg', 'Kendall_Ashley_Hilson_aged.jpg', 'Kayla_Marie_Williams_aged.jpg', 'Kaushik_Rajaram_aged.jpg', 'Latham_Alexander_Weaver_aged.jpg', 'Trinity_Nicole_Elliott_aged.jpg', 'Reid_Powers_Walker_aged.jpg', 'Bingnan_Lei_aged.jpg', 'Andrea_Chen_aged.jpg', 'Savannah_Kayla_Littlejohn_aged.jpg', 'Jash_Sanjaybhai_Vachhani_aged.jpg', 'Elizabeth_G_Higgins_aged.jpg', 'Estefani_Santiago_Gatica_aged.jpg', 'Qin_Miao_aged.jpg', 'Yue_Zhou_aged.jpg', 'Niklas_Jozef_Baldis_aged.jpg', 'Hanshuai_Shi.jpg', 'Edward_Cheongjoun_Hyun_aged.jpg', 'Christopher_Craig_Kenney.jpg', 'Xiyan_Huang.jpg', 'Lauren_Elizabeth_Johnson_aged.jpg', 'Angela_Waszkiewicz.jpg', 'Tianyu_Cui.jpg', 'Jiaming_Zhang_aged.jpg', 'Xiaoya_Luo_aged.jpg', 'Nathalie_Lisa_Friedman_aged.jpg', 'Shenger_Zhou_aged.jpg', 'Jiahua_Wu.jpg', 'Hewei_Shen.jpg', 'Andrew_Dubois.jpg', 'Emmanuel_Thomas_George_Skora.jpg', 'John_William_Null_aged.jpg', 'Bingyu_Li.jpg', 'Jodie_Elizabeth_Brine.jpg', 'Meryl_Criswell_Kaduboski.jpg', 'Amanda_Renner_Gild.jpg', 'Michael_Jason_Vejsiri_aged.jpg', 'Patrick_Ryan_Weimaker_aged.jpg', 'Zihe_Liu.jpg', 'Emmanuel_Thomas_George_Skora_aged.jpg', 'Daniel_Madden_Sheedy_aged.jpg', 'Zaul_Alexander_Perez_aged.jpg', 'Lu_Xing_aged.jpg', 'Niklas_Jozef_Baldis.jpg', 'Kendall_Ashley_Hilson.jpg', 'Shenzhe_Lian_aged.jpg', 'Dillon_Hunter_Aryeh_aged.jpg', 'Nathanael_Hunter_Kraus_aged.jpg', 'Tianyi_Yin_aged.jpg', 'Cole_Ritchey.jpg', 'Bingnan_Lei.jpg', 'Zaul_Alexander_Perez.jpg', 'Max_Koontz.jpg', 'Yiming_Xu.jpg', 'Evan_Anderson_Gilbert.jpg', 'Xiyue_Yu_aged.jpg', 'Cheuk_Yui_Marcus_Chan_aged.jpg', 'Shuzhe_Wang_aged.jpg', 'Helen_Kidane_Haile.jpg', 'Harve_E_Criqui.jpg', 'Khushi_Arya_aged.jpg', 'Anne_M_Perry_aged.jpg', 'Jash_Sanjaybhai_Vachhani.jpg', 'George_Basil_Economus_aged.jpg', 'Mary_Michele_Troise_aged.jpg', 'Samantha_O_Brien.jpg', 'Boyan_Wei_aged.jpg', 'Luying_Huang_aged.jpg', 'Meghan_O_Malley_aged.jpg', 'Alfredo_Enrique_Suarez_aged_aged.jpg', 'Boyu_Zheng.jpg', 'Quinn_Poole.jpg', 'Daniel_Madden_Sheedy.jpg', 'Guangxin_Bao.jpg', 'Tianyi_Chen.jpg', 'Andrew_Dubois_aged.jpg', 'Ryan_Marek_Smith.jpg', 'Dillon_Hunter_Aryeh.jpg', 'Meryl_Criswell_Kaduboski_aged.jpg', 'Chioke_K_Bellamy_aged.jpg', 'Marcus_Cole_cooper.jpg', 'Harve_E_Criqui_aged.jpg', 'Anthony_X_Ayala.jpg', 'Nathalie_Lisa_Friedman.jpg', 'Bintong_Zhai_aged.jpg', 'Quinn_Poole_aged.jpg', 'Logan_Trujillo_aged.jpg', 'Savannah_Kayla_Littlejohn.jpg', 'Christopher_Craig_Kenney_aged.jpg', 'Ryan_Marek_Smith_aged.jpg', 'Bryce_Charles_Drynan_aged.jpg', 'Nicolson_Charles_Panos_aged.jpg', 'Yuchen_Qin_aged.jpg', 'Marcus_Cole_cooper_aged.jpg', 'Xiaoyu_Zong_aged.jpg', 'Shuzhe_Wang.jpg', 'Songlin_Liu.jpg', 'Boyu_Zheng_aged.jpg', 'Ruochen_Bao_aged.jpg', 'Millie_C_Garrett.jpg', 'Chengzhan_Shen.jpg', 'Xiaoyang_Zheng.jpg', 'Allen_Gail_Smith.jpg', 'Reid_Powers_Walker.jpg', 'Jeremy_Brian_Nurding_aged.jpg', 'Qian_Chen.jpg', 'Yutong_Ouyang.jpg', 'Natalie_Weiner_aged.jpg', 'Alfredo_Enrique_Suarez_aged.jpg', 'Edward_Cheongjoun_Hyun.jpg', 'Alicia_Rand_Bodoia.jpg', 'Millie_C_Garrett_aged.jpg', 'Whitney_Joyce_Isbell_aged.jpg', 'Hangfei_Lyu_aged.jpg', 'Angela_Waszkiewicz_aged.jpg', 'Shenzhe_Lian.jpg', 'Shenghao_Yang.jpg', 'Yilin_Wang_aged.jpg', 'Andrew_Lloyd_Loftis_aged.jpg', 'Jennifer_Ontiveros-Olivas_aged.jpg', 'Kaushik_Rajaram.jpg', 'Shenger_Zhou.jpg', 'Yanghua_Zhang_aged.jpg', 'Latham_Alexander_Weaver.jpg', 'Jacob_Philip_Rockaway.jpg', 'Khushi_Arya.jpg', 'Skylour_Sebastian_Winakur_aged.jpg', 'Jiahao_Ma_aged.jpg', 'Yutong_Ouyang_aged.jpg', 'Jeremy_Brian_Nurding.jpg', 'Raleigh_Coolidge_Conway.jpg', 'Andrew_Lloyd_Loftis.jpg', 'Ruochen_Bao.jpg', 'Kaamil_Farooqi.jpg', 'Songlin_Liu_aged.jpg', 'Jiahao_Ma.jpg', 'Garhett_William_Sessions.jpg', 'Hangfei_Lyu.jpg', 'Jackson_R_Harper.jpg', 'Michael_Jason_Vejsiri.jpg', 'Yuchen_Qin.jpg', 'Xiaoya_Luo.jpg', 'Cheuk_Yui_Marcus_Chan.jpg', 'Alfredo_Enrique_Suarez.jpg', 'Qin_Miao.jpg', 'Elizabeth_G_Higgins.jpg', 'Evan_Anderson_Gilbert_aged.jpg', 'Sebastian_Andres_Lopez-Ibanez.jpg', 'Natalie_Weiner.jpg', 'Jax_Francis_Revfi_aged.jpg', 'Shanay_Nimish_Sonawala_aged.jpg', 'Jax_Francis_Revfi.jpg', 'Mengyao_Liu_aged.jpg', 'Kaitlyn_R_Vickers.jpg', 'Jodie_Elizabeth_Brine_aged.jpg', 'Anthony_X_Ayala_aged.jpg', 'Shenghao_Yang_aged.jpg', 'Mary_Martha_Milcoff_aged.jpg', 'Christopher_David_Koontz_aged.jpg', 'Eric_Mayo_aged.jpg', 'Michelle_Monica_Saikali_aged.jpg', 'Kyle_John_Wiblishauser_aged.jpg', 'Xiyan_Huang_aged.jpg', 'Anoush_U_Shah_aged.jpg', 'Xingyu_Wan_aged.jpg', 'Hanshuai_Shi_aged.jpg', 'Lu_Xing.jpg', 'Wentong_Guo.jpg', 'Raleigh_Coolidge_Conway_aged.jpg', 'Yilin_Wang.jpg', 'Dongqiao_Tang.jpg', 'Kayla_Marie_Williams.jpg', 'Mengyao_Liu.jpg', 'Trinity_Nicole_Elliott.jpg', 'Siyu_Lin_aged.jpg', 'Max_Koontz_aged.jpg', 'Shanay_Nimish_Sonawala.jpg', 'Luying_Huang.jpg', 'Bintong_Zhai.jpg', 'Haopeng_Liu_aged.jpg', 'Kaamil_Farooqi_aged.jpg', 'Xiaoyu_Zong.jpg', 'Whitney_Joyce_Isbell.jpg', 'Nicholas_J_Sundberg.jpg', 'John_William_Null.jpg', 'Jiacheng_Wang.jpg', 'Tianyi_Yin.jpg', 'Lauren_Elizabeth_Johnson.jpg', 'Chengzhan_Shen_aged.jpg', 'Estefani_Santiago_Gatica.jpg', 'Alicia_Rand_Bodoia_aged.jpg', 'Boyan_Wei.jpg', 'Jiahua_Wu_aged.jpg', 'Allen_Gail_Smith_aged.jpg', 'Xiaoyang_Zheng_aged.jpg', 'Siyu_Lin.jpg', 'Mary_Michele_Troise.jpg', 'Nicolson_Charles_Panos.jpg', 'Tianyu_Cui_aged.jpg', 'Jiaming_Zhang.jpg', 'Xiyue_Yu.jpg', 'Mary_Martha_Milcoff.jpg', 'Bingyu_Li_aged.jpg', 'Benjamin_Pyung-Hwa_Aikens.jpg', 'Tianyi_Chen_aged.jpg', 'Guangxin_Bao_aged.jpg', 'Chioke_K_Bellamy.jpg', 'Joseph_Miller_Hirsch_aged.jpg', 'Anoush_U_Shah.jpg', 'Joseph_Miller_Hirsch.jpg', 'Sebastian_Andres_Lopez-Ibanez_aged.jpg', 'Joseph_Macon_Barker_aged.jpg', 'Christopher_David_Koontz.jpg', 'Bryce_Charles_Drynan.jpg', 'Jacob_Philip_Rockaway_aged.jpg', 'Wentong_Guo_aged.jpg', 'Anne_M_Perry.jpg', 'Yanghua_Zhang.jpg', 'Qian_Chen_aged.jpg', 'Yue_Zhou.jpg']
This process would take a lot of time. So I saved it to a pickle file and import it in whenever needed
# face_dict = {}
# for file in jpeg_files:
# # load image
# img = face_recognition.load_image_file(f"./2024_students/{file}")
# # detect faces in the image
# face_locations = face_recognition.face_locations(img)
# if len(face_locations) > 0:
# # get encoding
# enc = face_recognition.face_encodings(img)[0]
# face_dict[file] = enc
# else:
# print(f"No face detected in {file}")
# Save the dictionary so we don't have to re-run the encoding step again
# with open('face_dict.pickle', 'wb') as f:
# pickle.dump(face_dict, f)
face_dict = {}
with open("face_dict.pickle", "rb") as f:
face_dict = pickle.load(f)
# convert to dataframe
data_items = list(face_dict.items())
# Create DataFrame
face_df = pd.DataFrame(data_items, columns=['image', 'encoding'])
face_df.head()
| image | encoding | |
|---|---|---|
| 0 | Alfredo_Enrique_Suarez.jpg | [-0.14946380257606506, -0.018561195582151413, ... |
| 1 | Alfredo_Enrique_Suarez_aged.jpg | [-0.18067379295825958, -0.020742785185575485, ... |
| 2 | Alfredo_Enrique_Suarez_aged_aged.jpg | [-0.16252249479293823, -0.035916682332754135, ... |
| 3 | Alicia_Rand_Bodoia.jpg | [-0.04311027750372887, 0.021171540021896362, 0... |
| 4 | Alicia_Rand_Bodoia_aged.jpg | [-0.0516541562974453, 0.08393877744674683, 0.1... |
# face match function
def match_faces(source_image, target_image):
"""
Args:
source_image: image to be matched against
target_image: image to be matched
Returns:
similarity score between 0 and 100
"""
if source_image in face_df['image'].values and target_image in face_df['image'].values:
enc1 = face_df.loc[face_df['image'] == source_image, 'encoding'].iloc[0]
enc2 = face_df.loc[face_df['image'] == target_image, 'encoding'].iloc[0]
face_distance = face_recognition.face_distance([enc1], enc2)
similarity = 1 - face_distance[0]
return similarity * 100
else:
return None
match_faces('Alfredo_Enrique_Suarez.jpg','Alfredo_Enrique_Suarez_aged.jpg')
62.890925297757775
III. Performance Evaluation¶
match_file['match_similarity'] = match_file.apply(lambda row: match_faces(row['source_image'], row['target_image']), axis=1)
Use a threshold of 50% to decide where the two face is a match or not.
match_file['predicted_match'] = np.where(match_file['match_similarity'] > 50, 'match','no match')
# Calculate confusion matrix
matrix = confusion_matrix(match_file['expected_match'],
match_file['predicted_match'],
labels=["match", "no match"])
print(matrix)
[[110 16] [ 2 48]]
# Calculate confusion matrix
y_true = match_file['expected_match']
y_pred = match_file['predicted_match']
labels = ["match", "no match"]
matrix = confusion_matrix(y_true, y_pred, labels=labels)
# specificity
specificity = matrix[1,1]/(matrix[1,0]+matrix[1,1])
# Calculate Accuracy, Precision and Recall
accuracy = accuracy_score(y_true, y_pred)
precision = precision_score(y_true, y_pred, pos_label="match")
recall = recall_score(y_true, y_pred, pos_label="match")
print("Accuracy:", accuracy)
print("Precision:", precision)
print("Recall:", recall)
print("Specificity:", specificity)
Accuracy: 0.8977272727272727 Precision: 0.9821428571428571 Recall: 0.873015873015873 Specificity: 0.96
# Plotting using seaborn
plt.figure(figsize=(8, 6))
sns.heatmap(matrix, annot=True, fmt="d", xticklabels=labels, yticklabels=labels, cmap="Blues")
plt.title("Confusion Matrix of face_recognition open source library")
plt.ylabel('Actual')
plt.xlabel('Predicted')
plt.show()
Lower the threshold to 35
match_file['predicted_match_35'] = np.where(match_file['match_similarity'] > 35, 'match','no match')
# Calculate confusion matrix
matrix = confusion_matrix(match_file['expected_match'],
match_file['predicted_match_35'],
labels=["match", "no match"])
print(matrix)
[[118 8] [ 3 47]]
# Calculate confusion matrix
y_true = match_file['expected_match']
y_pred = match_file['predicted_match_35']
labels = ["match", "no match"]
matrix = confusion_matrix(y_true, y_pred, labels=labels)
# specificity
specificity = matrix[1,1]/(matrix[1,0]+matrix[1,1])
# Calculate Accuracy, Precision and Recall
accuracy = accuracy_score(y_true, y_pred)
precision = precision_score(y_true, y_pred, pos_label="match")
recall = recall_score(y_true, y_pred, pos_label="match")
print("Accuracy:", accuracy)
print("Precision:", precision)
print("Recall:", recall)
print("Specificity:", specificity)
Accuracy: 0.9375 Precision: 0.9752066115702479 Recall: 0.9365079365079365 Specificity: 0.94
# a histogram to visualize the distribution of the match_similarity
plt.figure(figsize=(8, 6))
sns.histplot(data=match_file, x="match_similarity", hue="expected_match", kde=False)
plt.title("Match Similarity Distribution of face_recognition open source library")
plt.show()
IV. Examples¶
1. Expected Match¶
For the first expected match comparision, I will examine its performance on Boyu's face and his aged version
# 1. Load two images using load_image_file
face_file1 = "Boyu_Zheng.jpg"
face_file2 = "Boyu_Zheng_aged.jpg"
# 2. Compare the face_encodings similarity using face_distance
similarity = match_faces(face_file1, face_file2)
# Print the similarity score
print("The two faces are '{:.2f}%' similar".format(similarity))
The two faces are '63.12%' similar
face_file1 = "./2024_students/Boyu_Zheng.jpg"
face_file2 = "./2024_students/Boyu_Zheng_aged.jpg"
display_compare_face(face_file1, face_file2)
For the second expected match comparision, I will examine Tianyi_Yin's face and her aged version
# 1. Load two images using load_image_file
face_file1 = "Tianyi_Yin.jpg"
face_file2 = "Tianyi_Yin_aged.jpg"
# 2. Compare the face_encodings similarity using face_distance
similarity = match_faces(face_file1, face_file2)
# Print the similarity score
print("The two faces are '{:.2f}%' similar".format(similarity))
The two faces are '49.74%' similar
face_file1 = "./2024_students/Tianyi_Yin.jpg"
face_file2 = "./2024_students/Tianyi_Yin_aged.jpg"
display_compare_face(face_file1, face_file2)
Though this is the same person, the model fails to recognize and the match similarity is below the threshold.
2. Expected Non-Match¶
For the first expected non-match comparision, I will examine the the facial comparision betweeen aged Boyu and aged Wei Tan
# 1. Load two images using load_image_file
face_file1 = "Wei_Tan_aged.jpg"
face_file2 = "Boyu_Zheng_aged.jpg"
# 2. Compare the face_encodings similarity using face_distance
similarity = match_faces(face_file1, face_file2)
# Print the similarity score
print("The two faces are '{:.2f}%' similar".format(similarity))
The two faces are '48.93%' similar
face_file1 = "./2024_students/Boyu_Zheng_aged.jpg"
face_file2 = "./2024_students/Wei_Tan_aged.jpg"
display_compare_face(face_file1, face_file2)
The match similarity is below the threshold, indicating the two faces are different, which is correct
For the second expected non-match facial comparision, I will examine Chenzhan Shen and the aged version of Xiaoya Luo
# 1. Load two images using load_image_file
face_file1 = "Chengzhan_Shen.jpg"
face_file2 = "Xiaoya_Luo_aged.jpg"
# 2. Compare the face_encodings similarity using face_distance
similarity = match_faces(face_file1, face_file2)
# Print the similarity score
print("The two faces are '{:.2f}%' similar".format(similarity))
The two faces are '51.79%' similar
face_file1 = "./2024_students/Chengzhan_Shen.jpg"
face_file2 = "./2024_students/Xiaoya_Luo_aged.jpg"
display_compare_face(face_file1, face_file2)